package de.ifi.lmu.snitzelhunt.util;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import de.ifi.lmu.snitzelhunt.basics.Route;
import de.ifi.lmu.snitzelhunt.database.DBHelper;
import de.ifi.lmu.snitzelhunt.database.RouteTable;
import de.ifi.lmu.snitzelhunt.util.responses.AsyncDatabase_Route_CreateResponse;
import de.ifi.lmu.snitzelhunt.util.responses.AsyncDatabase_Route_DeleteResponse;
import de.ifi.lmu.snitzelhunt.util.responses.AsyncDatabase_Route_ReadResponse;
import de.ifi.lmu.snitzelhunt.util.responses.AsyncDatabase_Route_UpdateResponse;

/**
 * Utilities for handling operations on the local SQLlite database
 * 
 * @author jaschkowitz
 */
public class DatabaseUtility {

	/**
	 * Method to add a Route to the local SQLlite Database. An AsyncTask is used
	 * to start a new thread outside of the UI Thread.
	 * {@link AsyncDatabase_Route_CreateResponse} target is used for the caller
	 * to get the ID in the local Database of the inserted Row
	 * 
	 * @param route
	 *            The route to add
	 * @param context
	 *            An Android Context
	 * @param target
	 *            The class that wants the response
	 */
	public void createRoute(Route route, Context context,
			AsyncDatabase_Route_CreateResponse target) {
		new CreateRouteTask(context, target).execute(route);
	}

	/**
	 * Method to update a Route in the local SQLlite Database. An AsyncTask is
	 * used to start a new thread outside of the UI Thread.
	 * {@link AsyncDatabase_Route_UpdateResponse} target is used for the caller
	 * to implement a UI notification
	 * 
	 * @param route
	 *            The route to change
	 * @param context
	 *            An Android Context
	 * @param target
	 *            The class that wants the response
	 */
	public void updateRoute(Route route, Context context,
			AsyncDatabase_Route_UpdateResponse target) {
		new UpdateRouteTask(context, target).execute(route);
	}

	/**
	 * Method to get a Route from the local SQLlite Database. An AsyncTask is
	 * used to start a new thread outside of the UI Thread.
	 * {@link AsyncDatabase_Route_ReadResponse} target is used for the caller to
	 * get the route
	 * 
	 * @param localID
	 *            The id of the route to get
	 * @param context
	 *            An Android Context
	 * @param target
	 *            The class that wants the response
	 */
	public void readRoute(long localID, Context context,
			AsyncDatabase_Route_ReadResponse target) {
		new ReadRouteTask(context, target).execute(localID);
	}

	/**
	 * Method to delete a Route from the local SQLlite Database. An AsyncTask is
	 * used to start a new thread outside of the UI Thread.
	 * {@link AsyncDatabase_Route_ReadResponse} target is used for the caller to
	 * delete the route
	 * 
	 * @param localID
	 *            The id of the route to delete
	 * @param context
	 *            An Android Context
	 * @param target
	 *            The class that wants the response
	 */
	public void deleteRoute(long localID, Context context,
			AsyncDatabase_Route_DeleteResponse target) {
		new DeleteRouteTask(context, target).execute(localID);
	}

	/**
	 * AsyncTask to add a Route to the local SQLlite Database.
	 * 
	 * @author jaschkowitz
	 * 
	 */
	private class CreateRouteTask extends AsyncTask<Route, Void, Long> {
		private final Context mcont;
		private AsyncDatabase_Route_CreateResponse target;

		private CreateRouteTask(Context context,
				AsyncDatabase_Route_CreateResponse targetAct) {
			super();
			mcont = context;
			target = targetAct;
		}

		@Override
		protected Long doInBackground(Route... params) {
			Route route = params[0];
			SQLiteDatabase sqldb = DBHelper.getHelper(mcont)
					.getWritableDatabase();
			long localID = RouteTable.insertRoute(sqldb, route);
			sqldb.close();
			return localID;
		}

		@Override
		protected void onPostExecute(Long localID) {
			target.processDatabase_Route_Create(localID);
		}
	}

	/**
	 * AsyncTask to update a Route in the local SQLlite Database.
	 * 
	 * @author jaschkowitz
	 * 
	 */
	private class UpdateRouteTask extends AsyncTask<Route, Void, Void> {
		private final Context mcont;
		private AsyncDatabase_Route_UpdateResponse target;

		private UpdateRouteTask(Context context,
				AsyncDatabase_Route_UpdateResponse targetAct) {
			super();
			mcont = context;
			target = targetAct;
		}

		@Override
		protected Void doInBackground(Route... params) {
			Route route = params[0];
			SQLiteDatabase sqldb = DBHelper.getHelper(mcont)
					.getWritableDatabase();
			RouteTable.updateLocalRoute(sqldb, route);
			sqldb.close();
			return null;
		}

		protected void onPostExecute(Void Result) {
			target.processDatabase_Route_Update();
		}
	}

	/**
	 * AsyncTask to get a Route from the local SQLlite Database.
	 * 
	 * @author jaschkowitz
	 * 
	 */
	private class ReadRouteTask extends AsyncTask<Long, Void, Route> {
		private final Context mcont;
		private AsyncDatabase_Route_ReadResponse target;

		private ReadRouteTask(Context context,
				AsyncDatabase_Route_ReadResponse targetAct) {
			super();
			mcont = context;
			target = targetAct;
		}

		@Override
		protected Route doInBackground(Long... params) {
			SQLiteDatabase sqldb = DBHelper.getHelper(mcont)
					.getReadableDatabase();
			Route loadRoute = RouteTable.getRoute(sqldb, params[0]);
			sqldb.close();
			return loadRoute;
		}

		protected void onPostExecute(Route resultRoute) {
			target.processDatabase_Route_Read(resultRoute);
		}
	}

	/**
	 * AsyncTask to delete a Route from the local SQLlite Database.
	 * 
	 * @author jaschkowitz
	 * 
	 */
	private class DeleteRouteTask extends AsyncTask<Long, Void, Void> {
		private final Context mcont;
		private AsyncDatabase_Route_DeleteResponse target;

		private DeleteRouteTask(Context context,
				AsyncDatabase_Route_DeleteResponse targetAct) {
			super();
			mcont = context;
			target = targetAct;
		}

		@Override
		protected Void doInBackground(Long... params) {
			SQLiteDatabase sqldb = DBHelper.getHelper(mcont)
					.getReadableDatabase();
			RouteTable.deleteLocalRoute(sqldb, params[0]);
			sqldb.close();
			return null;
		}

		protected void onPostExecute(Void Result) {
			target.processDatabase_Route_Delete();
		}
	}

}
